package com.fingard.dsp.bank.directbank.cib01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IBalance;
import com.fingard.dsp.bank.reqrespobj.ReqRespHeader;
import com.fingard.dsp.bank.reqrespobj.balance.Req7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.Req7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.detail.Req7506Detail;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsBalDetail;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsHisBalDetail;
import com.fingard.dsp.bank.reqrespobj.enumeration.ENDirectRight;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhangfujia
 * @time 20160905
 */
@Component("CIB01Balance")
public class CIB01Balance extends CIB01Base implements IBalance {
    private final String successCode = "0";

	/**
	 * 单个余额查询，统一采用流处理方式
	 *1、循环调用Req7506BalQry.readRecord()读取一个请求明细，然后写入发银行的XML对象
	 *2、发银行
	 *3、循环调用XmlTextReader.read()读取一个银行返回节点，赋值返回ATS的明细对象，
	 *  然后调用RetAts7506BalQry.writeRetDetail()，写入返回ATS的明细
	*/
	@Override
	public RetAts7506BalQry d_7506_BalQry(Req7506BalQry p_req7506) throws Exception{//余额查询
		//余额查询返回ATS的对象
		RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
		retAts.writeStart();//写返回ATS的统一头部信息
		try {
			while(p_req7506.readRecord()){//不支持批量查询，逐个查询
				//赋值通用参数
				XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
				writeCommonHeader(xmlWriter);
				RetAtsBalDetail tmpRetDetail = new RetAtsBalDetail();
				tmpRetDetail.actNum = p_req7506.readedDetail.actNum;
				//写入通用的头部节点
				xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
				xmlWriter.writeStartElement("STMTTRNRQ");
				xmlWriter.writeElementString("TRNUID",p_req7506.reqHeader.transSeqID);
				xmlWriter.writeStartElement("STMTRQ");
				xmlWriter.writeStartElement("ACCTFROM");
				//写入账号
				xmlWriter.writeElementString("ACCTID", p_req7506.readedDetail.actNum);
				xmlWriter.writeEndElement();
				xmlWriter.writeEndDocument();
				String xmlSend = writeContentLength(xmlWriter);
				String[] tmpStrRet = sendToBank(xmlSend, p_req7506.reqHeader.transType, p_req7506.reqHeader.transType);
				if(tmpStrRet[0].length() == 0){
					StringBuilder tmpSbMsg = new StringBuilder();
					String returnXml =tmpStrRet[1].substring(tmpStrRet[1].indexOf("<FOX>"), tmpStrRet[1].length());

					XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbMsg);
					if(tmpBkReader != null){
						//获取银行响应代码，返回值为000或002表示处理成功，否则为处理失败
						String tmpRetCode = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/STMTTRNRS/STATUS/CODE");
						if(tmpRetCode != null && successCode.equals(tmpRetCode)){
								tmpRetDetail.respCode = "0";
								tmpRetDetail.respInfo = "success";
								//获取币种
								tmpRetDetail.actCur = p_req7506.readedDetail.actCur;
								//获取账户
								tmpRetDetail.actNum = p_req7506.readedDetail.actNum;
								//获取可用余额，如果balSign为“+”表示金额为正，为“-”表示金额为负
								tmpRetDetail.availBal=tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/STMTTRNRS/STMTRS/AVAILBAL/BALAMT") ;
								//获取冻结金额
							//	tmpRetDetail.frozenBal=tmpBkReader.readedXElement.getSingleText("freeze");
								//获取实际余额
								tmpRetDetail.currBal =tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/STMTTRNRS/STMTRS/LEDGERBAL/BALAMT");
								//获取最后交易时间
								tmpRetDetail.lastTranDate=tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/STMTTRNRS/STMTRS/LEDGERBAL/DTASOF");
								//获取现金池用户余额
								if(p_req7506.readedDetail.directRight.contains(ENDirectRight.CASHPOOLS.getValue())){
									String cashPoolAvailBal=d_7506_BalQry_balPool(p_req7506.readedDetail,p_req7506.reqHeader);
									if(StringHelper.hasAnyChar(cashPoolAvailBal)){
										tmpRetDetail.cashPoolAvailBal=cashPoolAvailBal;
									}else {
										WriteBankLogLn("获取到的现金池可用余额为空，请检查报文");
									}
								}
						}
						//处理失败respCode返回为-1
						else{
							tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/STMTTRNRS/STATUS/SEVERITY");
						}
					}
					else{
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpSbMsg.toString();
					}
				}
				else{
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpStrRet[1];
				}
				retAts.writeRetDetail(tmpRetDetail, p_req7506.isBatch);
			}
		} catch (Exception e) {
			retAts.writeRespCode("-1");
			retAts.writeRespInfo(e.getMessage());
			e.printStackTrace();
		}
		retAts.writeEnd();
		return retAts;
	}

	@Override
	public RetAts7505HisBalQry d_7505_BalQry(Req7505HisBalQry p_req7505) throws Exception {
        RetAts7505HisBalQry retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
        retAts.writeStart();//写返回ATS的统一头部信息
        String tmpRespCode = "";
        String tmpRespInfo = "";
        try {
            //先查询现金池权限历史余额
			Map<String,String> balPoolMap=new HashMap<String, String>();
			if(p_req7505.directRight.contains(ENDirectRight.CASHPOOLS.getValue())){
				balPoolMap=d_7505_BalQry_balPool(p_req7505);
			}
			//再查询普通权限账户历史余额
        	//发银行报文的XML对象
            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter);
            xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
            xmlWriter.writeStartElement("HISBALQUERYTRNRQ");
            xmlWriter.writeElementString("TRNUID", p_req7505.reqHeader.transSeqID);
            xmlWriter.writeElementString("CLTCOOKIE", "");
            xmlWriter.writeStartElement("HISBALQUERYRQ");
            xmlWriter.writeStartElement("HISBALQUERYINFO");
            //写入查询条件
            xmlWriter.writeElementString("ACCTID", p_req7505.actNum);
            xmlWriter.writeElementString("ACCTNAME", "");
            xmlWriter.writeElementString("DTSTART", DateHelper.convertD8toD10(p_req7505.dateFrom));
            xmlWriter.writeElementString("DTEND", DateHelper.convertD8toD10(p_req7505.dateTo));
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            String xmlSend = writeContentLength(xmlWriter);
            String[] tmpStrRet = sendToBank(xmlSend, p_req7505.reqHeader.transType, p_req7505.reqHeader.transType);
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                String returnXml = tmpStrRet[1].substring(tmpStrRet[1].indexOf("<FOX>"), tmpStrRet[1].length());
                XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbMsg);
                if (tmpBkReader != null) {
                    //获取银行响应代码，返回值为000或002表示处理成功，否则为处理失败
                    String tmpRetCode = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/HISBALQUERYTRNRS/STATUS/CODE");
                    if (tmpRetCode != null && successCode.equals(tmpRetCode)) {
                        while (tmpBkReader.read("/FOX/SECURITIES_MSGSRSV1/HISBALQUERYTRNRS/HISBALQUERYRS/HISBALQUERYINFO/DETAILS/DETAIL")) {
                            RetAtsHisBalDetail tmpRetAtsHisBalDetail = new RetAtsHisBalDetail();
                            tmpRetAtsHisBalDetail.balDate = tmpBkReader.readedXElement.getSingleText("DTFLOW");
                            tmpRetAtsHisBalDetail.actBal = tmpBkReader.readedXElement.getSingleText("HISBALANCE");
                            if(balPoolMap!=null && balPoolMap.size()>0){
                            	//根据日期获取历史留存余额
                            	String cashPoolBal=balPoolMap.get(tmpRetAtsHisBalDetail.balDate);
                            	if(StringHelper.hasAnyChar(cashPoolBal)){
                            		tmpRetAtsHisBalDetail.cashPoolBal=cashPoolBal;
								}
							}
                            retAts.writeRetDetail(tmpRetAtsHisBalDetail);
                        }
                    }
                    //处理失败respCode返回为-1
                    else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/HISBALQUERYTRNRS/STATUS/MESSAGE");
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            tmpRespCode = "-1";
            tmpRespInfo = ex.toString();
        } finally {
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
			retAts.writeEnd();
        }
        return retAts;
    }

	/**
	 * 现金池账户历史余额查询
	 * @param p_req7505
	 * @return
	 * @throws Exception
	 */
	public Map<String,String> d_7505_BalQry_balPool(Req7505HisBalQry p_req7505) throws Exception {
		//定义返回值：历史留存余额
		Map<String,String> balPoolMap=new HashMap<String, String>();
		//查询页
		int page=1;
		//是否继续查询标识
		boolean isNext=true;
		while (isNext){
			isNext=false;
			//赋值通用参数
			XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
			writeCommonHeader(xmlWriter);
			xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
			xmlWriter.writeStartElement("CMHISBLNCTRNRQ");
			xmlWriter.writeElementString("TRNUID",getQryTransID());
			xmlWriter.writeElementAttribute("RQBODY","PAGE",page+"");
			xmlWriter.writeStartElement("FUNDACCT");//结算中心账号
			xmlWriter.writeElementString("ACCTID", getBankConfig().getMapValueByKey("orgAcctIdMapping",bankFront.org));
			xmlWriter.writeEndElement();
			xmlWriter.writeStartElement("MBRACCT");//成员单位账号
			xmlWriter.writeElementString("ACCTID", p_req7505.actNum);
			xmlWriter.writeEndElement();
			xmlWriter.writeElementString("DTSTART", Format.Date10Format.format(p_req7505.getDateFrom()));
			xmlWriter.writeElementString("DTEND", Format.Date10Format.format(p_req7505.getDateTo()));
			xmlWriter.writeEndDocument();
			String xmlSend = writeContentLength(xmlWriter);
			String[] tmpStrRet = sendToBank(xmlSend, reqHeader.transType, reqHeader.commandCode);
			if(tmpStrRet[0].length() == 0){
				StringBuilder tmpSbMsg = new StringBuilder();
				String returnXml =tmpStrRet[1].substring(tmpStrRet[1].indexOf("<FOX>"), tmpStrRet[1].length());
				XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbMsg);
				if(tmpBkReader != null){
					//获取银行响应代码
					String tmpRetCode = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/CMHISBLNCTRNRS/STATUS/CODE");
					if(tmpRetCode != null && successCode.equals(tmpRetCode)){
						//获取是否下一页标识
						tmpBkReader.read("/FOX/SECURITIES_MSGSRSV1/CMHISBLNCTRNRS/RSBODY");
						isNext="Y".equals(tmpBkReader.readedXElement.hashMapAttributes.get("MORE"));
						//获取当前页查询的历史留存余额
						List<XElement> contentList=tmpBkReader.readedXElement.getChildList("CONTENT");
						if(contentList!=null && contentList.size()>0){
							for(XElement content:contentList){
								//交易日期
								String date=content.getSingleTextNotNull("DTTRN");
								//历史留存金额
								String cashPoolBal=content.getSingleTextNotNull("CONTRBTRATE");
								balPoolMap.put(date,cashPoolBal);
							}
						}else {
							WriteBankLogLn("没有历史余额明细");
						}
					} else{
						WriteBankLogLn(tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/CMHISBLNCTRNRS/STATUS/SEVERITY"));
					}
				}else{
					WriteBankLogLn(tmpSbMsg.toString());
				}
			}else{
				WriteBankLogLn(tmpStrRet[1]);
			}
		}
		return balPoolMap;
	}

	/**
	 * 现金池账户余额查询
	 * @param readedDetail
	 * @return
	 * @throws Exception
	 */
	public String d_7506_BalQry_balPool(Req7506Detail readedDetail,ReqRespHeader reqHeader) throws Exception {
		//定义返回值：现金池可用余额
		String cashPoolAvailBal="";
		//赋值通用参数
		XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
		writeCommonHeader(xmlWriter);
		xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
		xmlWriter.writeStartElement("CMAVBLQUOTATRNRQ");
		xmlWriter.writeElementString("TRNUID",getQryTransID());
		xmlWriter.writeStartElement("RQBODY");
		xmlWriter.writeStartElement("FUNDACCT");
		xmlWriter.writeElementString("ACCTID", getBankConfig().getMapValueByKey("orgAcctIdMapping",bankFront.org));//结算中心账号
		xmlWriter.writeEndElement();
		xmlWriter.writeElementString("ACCTID", readedDetail.actNum);//成员单位账号
		xmlWriter.writeEndDocument();
		String xmlSend = writeContentLength(xmlWriter);
		String[] tmpStrRet = sendToBank(xmlSend, reqHeader.transType, reqHeader.commandCode);
		if(tmpStrRet[0].length() == 0){
			StringBuilder tmpSbMsg = new StringBuilder();
			String returnXml =tmpStrRet[1].substring(tmpStrRet[1].indexOf("<FOX>"), tmpStrRet[1].length());
			XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbMsg);
			if(tmpBkReader != null){
				//获取银行响应代码
				String tmpRetCode = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/CMAVBLQUOTATRNRS/STATUS/CODE");
				if(tmpRetCode != null && successCode.equals(tmpRetCode)){
					//获取现金池可用余额
					cashPoolAvailBal=tmpBkReader.getFirstTextNotNull("/FOX/SECURITIES_MSGSRSV1/CMAVBLQUOTATRNRS/RSBODY/CONTRBTRATE");
				} else{
					WriteBankLogLn(tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/CMAVBLQUOTATRNRS/STATUS/SEVERITY"));
				}
			}else{
				WriteBankLogLn(tmpSbMsg.toString());
			}
		}else{
			WriteBankLogLn(tmpStrRet[1]);
		}
		return cashPoolAvailBal;
	}
}
